package com.tk.exam.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonObject;
import com.tk.exam.dao.TkQuestionDao;
import com.tk.exam.dao.TkRPaperQuestionDao;
import com.tk.exam.domain.TkQuestions;
import com.tk.exam.domain.TkRPaperQuestion;
import com.tk.exam.domain.TkRPaperQuestionExample;
import com.tk.exam.exception.ApiException;
import com.tk.exam.service.TkQuestionService;
import com.tk.exam.utils.JsonUtils;
import com.tk.exam.vo.question.*;
import com.tk.exam.vo.question.req.*;
import com.tk.exam.vo.question.resp.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class TkQuestionServiceImpl implements TkQuestionService {
    private String types="1,2,3,4,5";

    @Autowired
    private TkQuestionDao tkQuestionDao;
    @Autowired
    private TkRPaperQuestionDao tkRPaperQuestionDao;

    @Override
    public PageInfo<TkQuestionVo> searchList(String category, String type) {
        PageInfo<TkQuestionVo> list = tkQuestionDao.selectQuestionWithPage(category,type);
        return list;
    }

    /**
     * 验证格式
     *
     * @param tkQuestion4CRequestVo
     * @return
     */
    @Override
    public boolean validate4c(TkQuestion4CRequestVo tkQuestion4CRequestVo) {
        if(!validatePub(tkQuestion4CRequestVo.getQuesTitle(),tkQuestion4CRequestVo.getQuesCategory(),tkQuestion4CRequestVo.getQuesType())){
            return false;
        }
        if(StringUtils.isBlank(tkQuestion4CRequestVo.getHasDefect())){
            throw ApiException.of("Error: hasDefect为空，入参错误");
        }
        if(CollectionUtils.isEmpty(tkQuestion4CRequestVo.getOptions())){
            throw ApiException.of("Error: options为空，入参错误");
        }
        List<Option> options = tkQuestion4CRequestVo.getOptions();
        List<Option> hasCheck = options.stream().filter(option -> "1".equals(option.getIsCheck())).collect(Collectors.toList());

        if("1".equals(tkQuestion4CRequestVo.getHasDefect()) && CollectionUtils.isEmpty(hasCheck)){
            throw ApiException.of("Error: 至少选择一个正确答案");
        }
        if("1".equals(tkQuestion4CRequestVo.getHasDefect()) && !hasCheckImage(tkQuestion4CRequestVo)){
            throw ApiException.of("Error: 至少选择一张图片");
        }

        //todo:问完路哥修改这块校验注释
//        if(!CollectionUtils.isEmpty(tkQuestion4CRequestVo.getAddSuspensionImages())){
//            throw ApiException.of("Error: catenaryImages为空，请上传图片");
//        }
//        if(!CollectionUtils.isEmpty(tkQuestion4CRequestVo.getCatenaryImages())){
//            throw ApiException.of("Error: catenaryImages为空，请上传图片");
//        }
//        if(!CollectionUtils.isEmpty(tkQuestion4CRequestVo.getDavitImages())){
//            throw ApiException.of("Error: davitImages为空，请上传图片");
//        }
//        if(!CollectionUtils.isEmpty(tkQuestion4CRequestVo.getSupportDeviceImages())){
//            throw ApiException.of("Error: supportDeviceImages为空，请上传图片");
//        }
        return true;
    }
    //检查是否选中图片
    public boolean hasCheckImage(TkQuestion4CRequestVo tkQuestion4CRequestVo){
        List<AddSuspensionImage> addSuspensionImages = tkQuestion4CRequestVo.getAddSuspensionImages();
        List<CatenaryImage> catenaryImages = tkQuestion4CRequestVo.getCatenaryImages();
        List<DavitImage> davitImages = tkQuestion4CRequestVo.getDavitImages();
        List<SupportDeviceImage> supportDeviceImages = tkQuestion4CRequestVo.getSupportDeviceImages();
        if(!CollectionUtils.isEmpty(addSuspensionImages)){
            List<AddSuspensionImage> checkAdds = addSuspensionImages.stream().filter(addImage->"1".equals(addImage.getHasCheck())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(checkAdds)){
                return true;
            }
        }
        if(!CollectionUtils.isEmpty(catenaryImages)){
            List<CatenaryImage> checkCates = catenaryImages.stream().filter(cateImage->"1".equals(cateImage.getHasCheck())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(checkCates)){
                return true;
            }
        }
        if(!CollectionUtils.isEmpty(davitImages)){
            List<DavitImage> checkDavits = davitImages.stream().filter(davitImage->"1".equals(davitImage.getHasCheck())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(checkDavits)){
                return true;
            }
        }
        if(!CollectionUtils.isEmpty(supportDeviceImages)){
            List<SupportDeviceImage> checkSupports = supportDeviceImages.stream().filter(supportImage->"1".equals(supportImage.getHasCheck())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(checkSupports)){
                return true;
            }
        }
        return false;
    }
    @Override
    public boolean validatePd(TkQuestionPDRequestVo tkQuestionPDRequestVo) {
        if(!validatePub(tkQuestionPDRequestVo.getQuesTitle(),tkQuestionPDRequestVo.getQuesCategory(),tkQuestionPDRequestVo.getQuesType())){
            return false;
        }
        if(StringUtils.isBlank(tkQuestionPDRequestVo.getChoseType())){
            throw ApiException.of("Error: hasDefect为空，入参错误");
        }
        return true;
    }
    @Override
    public boolean validateJs(TkQuestionJSRequestVo tkQuestionJsRequestVo) {
        if(!validatePub(tkQuestionJsRequestVo.getQuesTitle(),tkQuestionJsRequestVo.getQuesCategory(),tkQuestionJsRequestVo.getQuesType())){
            return false;
        }
//        if(StringUtils.isBlank(tkQuestionJsRequestVo.getContent())){
//            throw ApiException.of("Error: content为空，入参错误");
//        }
        return true;
    }

    @Override
    public boolean validateType(String type) {
        if(StringUtils.isBlank(type)){
            return false;
        }
        List<String> l = Arrays.asList(types.split(","));
        if(l.contains(type)){
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public TkQuestions save(TkQuestionRequestVo vo) {
        TkQuestions tkQuestions = new TkQuestions();
        Date date = new Date();
        tkQuestions.setCreateTime(date);
        tkQuestions.setUpdateTime(date);
        tkQuestions.setQuesCategory(Integer.valueOf(vo.getQuesCategory()));
        tkQuestions.setQuesTitle(vo.getQuesTitle());
        tkQuestions.setQuesType(new Byte(vo.getQuesType()));
        tkQuestions.setQuesContent(JSONObject.toJSONString(vo));
        if(!Objects.isNull(vo.getId())){
            tkQuestions.setId(vo.getId());
        }
        return tkQuestionDao.save(tkQuestions);
    }

    @Override
    public TkQuestions edit(JSONObject param,String type) {

        return null;
    }

    @Override
    public TkQuestionTotalVo findById(String id) {
        TkQuestions tkQuestions = tkQuestionDao.findById(id);
        if(Objects.isNull(tkQuestions)){
            return null;
        }
        TkQuestionTotalVo totalVo = new TkQuestionTotalVo();
        //4c题 1:单选题,2:判断题,3:填空题,4:计算题,5:4C题
        if("5".equals(tkQuestions.getQuesType().toString())){
            TkQuestion4CRespVo vo = JsonUtils.string2Object(tkQuestions.getQuesContent(), TkQuestion4CRespVo.class);
            vo.setId(tkQuestions.getId().toString());
            totalVo.setQues4c(vo);
        }
        if("4".equals(tkQuestions.getQuesType().toString())){
            TkQuestionJSRespVo vo = JsonUtils.string2Object(tkQuestions.getQuesContent(), TkQuestionJSRespVo.class);
            vo.setId(tkQuestions.getId().toString());
            totalVo.setQuesJs(vo);
        }
        if("3".equals(tkQuestions.getQuesType().toString())){
            TkQuestionJSRespVo vo = JsonUtils.string2Object(tkQuestions.getQuesContent(), TkQuestionJSRespVo.class);
            vo.setId(tkQuestions.getId().toString());
            totalVo.setQuesTk(vo);
        }
        if("2".equals(tkQuestions.getQuesType().toString())){
            TkQuestionPDRespVo vo = JsonUtils.string2Object(tkQuestions.getQuesContent(), TkQuestionPDRespVo.class);
            vo.setId(tkQuestions.getId().toString());
            totalVo.setQuesPd(vo);
        }
        if("1".equals(tkQuestions.getQuesType().toString())){
            TkQuestionDXRespVo vo = JsonUtils.string2Object(tkQuestions.getQuesContent(), TkQuestionDXRespVo.class);
            vo.setId(tkQuestions.getId().toString());
            totalVo.setQuesDx(vo);
        }
        return totalVo;
    }

    @Override
    public TkAnswerVo findAnswerById(String id) {
        TkQuestions tkquestion = tkQuestionDao.findById(id);
        if(Objects.isNull(tkquestion)){
            return null;
        }
        String type = tkquestion.getQuesType().toString();
        if("3".equals(type) || "4".equals(type)){
            return null;
        }
        TkAnswerVo answerVo = null;
        if("5".equals(type)){
            TkQuestion4CRespVo vo = JsonUtils.string2Object(tkquestion.getQuesContent(),TkQuestion4CRespVo.class);
            //
            List<AddSuspensionImage> addSuspensionImages = vo.getAddSuspensionImages();
            List<AddSuspensionImage> checkAddImages = addSuspensionImages.stream().filter(addSuspensionImage -> "1".equals(addSuspensionImage.getHasCheck())).collect(Collectors.toList());

            List<CatenaryImage> catenaryImages = vo.getCatenaryImages();
            List<CatenaryImage> checkCiImages = catenaryImages.stream().filter(catenaryImage -> "1".equals(catenaryImage.getHasCheck())).collect(Collectors.toList());

            List<DavitImage> davitImages = vo.getDavitImages();
            List<DavitImage> checkDiImages = davitImages.stream().filter(davitImage -> "1".equals(davitImage.getHasCheck())).collect(Collectors.toList());

            List<SupportDeviceImage> supportDeviceImages = vo.getSupportDeviceImages();
            List<SupportDeviceImage> checkSdImages = supportDeviceImages.stream().filter(supportDeviceImage -> "1".equals(supportDeviceImage.getHasCheck())).collect(Collectors.toList());

            List<Option> options = vo.getOptions();
            List<Option> checkOptions =options.stream().filter(option -> "1".equals(option.getIsCheck())).collect(Collectors.toList());
            TkAnswer4C answer4C = new TkAnswer4C();
            answer4C.setAddSuspensionImages(checkAddImages);
            answer4C.setCatenaryImages(checkCiImages);
            answer4C.setDavitImages(checkDiImages);
            answer4C.setSupportDeviceImages(checkSdImages);
            answer4C.setOptions(options);
            answer4C.setCheckOptions(checkOptions);
            answer4C.setHasDefect(vo.getHasDefect());
            answerVo = new TkAnswerVo();
            answerVo.setAnswer4C(answer4C);
            answerVo.setId(vo.getId());
            return answerVo;
        }
        if("2".equals(type)){
            TkQuestionPDRespVo vo = JsonUtils.string2Object(tkquestion.getQuesContent(),TkQuestionPDRespVo.class);
            TkAnswerPD tkAnswerPD = new TkAnswerPD();
            tkAnswerPD.setChoseType(vo.getChoseType());
            answerVo = new TkAnswerVo();
            answerVo.setId(vo.getId());
            answerVo.setAnswerPD(tkAnswerPD);
            return answerVo;
        }
        if("1".equals(type)){
            TkQuestionDXRespVo vo = JsonUtils.string2Object(tkquestion.getQuesContent(),TkQuestionDXRespVo.class);
            TkAnswerDX tkAnswerDX = new TkAnswerDX();
            List<Option> options = vo.getOptions();
            List<Option> checkOptions =options.stream().filter(option -> "1".equals(option.getIsCheck())).collect(Collectors.toList());
            tkAnswerDX.setOptions(options);
            tkAnswerDX.setCheckOptions(checkOptions);
            answerVo = new TkAnswerVo();
            answerVo.setId(vo.getId());
            answerVo.setAnswerDX(tkAnswerDX);
            return answerVo;
        }

        return null;
    }

    @Override
    @Transactional
    public void deleteQues(List<String> ids) {
        //检查是否有试卷引用试题
        List<Integer> idlist = ids.stream().map(id->Integer.valueOf(id)).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(idlist)){
            throw ApiException.of("ids不能为空");
        }
        if(checkQues(idlist)){
            throw ApiException.of("试题已被试卷引用，不能删除");
        }
        tkQuestionDao.deleteByIds(idlist);

    }
    @Override
    public boolean checkQues(List<Integer> ids){
        return tkRPaperQuestionDao.checkQues(ids);
    }

    @Override
    public boolean validateDx(TkQuestionDXRequestVo tkQuestionDXRequestVo) {
        if(!validatePub(tkQuestionDXRequestVo.getQuesTitle(),tkQuestionDXRequestVo.getQuesCategory(),tkQuestionDXRequestVo.getQuesType())){
            return false;
        }
        if(CollectionUtils.isEmpty(tkQuestionDXRequestVo.getOptions())){
            throw ApiException.of("Error: options为空，入参错误");
        }
        List<Option> checks = tkQuestionDXRequestVo.getOptions().stream().filter(option -> "1".equals(option.getIsCheck())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(checks)){
            throw ApiException.of("Error: 单选题请至少勾选一个正确答案");
        }
        if(checks.size()>1){
            throw ApiException.of("Error: 单选题至多勾选一个正确答案");
        }
        return true;
    }
    public boolean validatePub(String title,String category,String type){
        if (StringUtils.isEmpty(title)) {
            throw ApiException.of("Error: quesTitle为空，入参错误");
        }
        if(StringUtils.isBlank(category)){
            throw ApiException.of("Error: quesCategory为空，入参错误");
        }
        if(StringUtils.isBlank(type)){
            throw ApiException.of("Error: quesType为空，入参错误");
        }
        return true;
    }
}
